package com.lzq.mq.nameserver.core;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.lzq.mq.common.constants.BrokerConstants;
import com.lzq.mq.common.constants.NameServerConstants;
import com.lzq.mq.common.debug.DebugHelper;
import com.lzq.mq.nameserver.common.CommonCache;
import com.lzq.mq.nameserver.common.MasterSlaveReplicationProperties;
import com.lzq.mq.nameserver.common.NameserverProperties;
import com.lzq.mq.nameserver.common.TraceReplicationProperties;
import com.lzq.mq.nameserver.enums.ReplicationModeEnum;
import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Properties;
import java.util.Scanner;

@Slf4j
public class PropertiesLoader {

    private Properties properties;

    private void loadPropertiesFromFile() throws IOException {
        this.properties = new Properties();
        String mqHome = System.getenv(BrokerConstants.MQ_HOME);
        String propertyFilePath = mqHome + NameServerConstants.NAME_SERVER_CONFIG_PATH;
        properties.load(Files.newInputStream(new File(propertyFilePath).toPath()));

        NameserverProperties nameserverProperties = new NameserverProperties();
        nameserverProperties.setNameserverPwd(getStr("nameserver.password"));
        nameserverProperties.setNameserverUser(getStr("nameserver.user"));
        nameserverProperties.setNameserverPort(getInt("nameserver.port"));


        String mode = getStrCanBeNull("nameserver.replication.mode");
        if (StringUtil.isNullOrEmpty(mode) || mode.equals(ReplicationModeEnum.STANDALONE.getCode())) {
            mode = ReplicationModeEnum.STANDALONE.getCode();
            log.info("以单机模式启动");
        } else if (mode.equals(ReplicationModeEnum.TRACE.getCode())) {
            log.info("以链路模式启动");
            TraceReplicationProperties traceReplicationProperties = new TraceReplicationProperties();
            traceReplicationProperties.setNextNode(getStrCanBeNull("nameserver.replication.next.node"));
            nameserverProperties.setTraceReplicationProperties(traceReplicationProperties);
        } else if (mode.equals(ReplicationModeEnum.MASTER_SLAVE.getCode())) {
            log.info("以主从模式启动");
            MasterSlaveReplicationProperties masterSlaveReplicationProperties = new MasterSlaveReplicationProperties();
            masterSlaveReplicationProperties.setMaster(getStrCanBeNull("nameserver.replication.master"));
            masterSlaveReplicationProperties.setRole(getStrCanBeNull("nameserver.replication.master.slave.role"));
            masterSlaveReplicationProperties.setType(getStrCanBeNull("nameserver.replication.master.slave.type"));
            masterSlaveReplicationProperties.setPort(getInt("nameserver.replication.port"));
            nameserverProperties.setMasterSlaveReplicationProperties(masterSlaveReplicationProperties);
        }
        nameserverProperties.setReplicationMode(mode);
        log.info("成功加载配置:{}", JSON.toJSONString(this, SerializerFeature.PrettyFormat));
        CommonCache.setNameserverProperties(nameserverProperties);
    }

    public void loadProperties() throws IOException {
        loadPropertiesFromFile();
        if (DebugHelper.DEBUG) {
            Scanner scanner = new Scanner(System.in);
            System.out.print("请输入节点角色:");
            String role = scanner.nextLine();
            NameserverProperties nameserverProperties = CommonCache.getNameserverProperties();
            nameserverProperties.getMasterSlaveReplicationProperties().setRole(role);
        }

    }

    private String getStrCanBeNull(String key) {
        String value = properties.getProperty(key);
        if (value == null) {
            return "";
        }
        return value;
    }

    private String getStr(String key) {
        String value = properties.getProperty(key);
        if (value == null) {
            throw new RuntimeException("配置参数：" + key + "不存在");
        }
        return value;
    }

    private Integer getInt(String key) {
        return Integer.valueOf(getStr(key));
    }

    public String getProperty(String key) {
        return properties.getProperty(key);
    }
}